#!/bin/bash -e
#
#   Neutron3529's Unity Game Plugin
#   Copyright (C) 2022 Neutron3529
#
#   This program is free software: you can redistribute it and/or modify
#   it under the terms of the GNU Affero General Public License as
#   published by the Free Software Foundation, either version 3 of the
#   License, or (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU Affero General Public License for more details.
#
#   You should have received a copy of the GNU Affero General Public License
#   along with this program.  If not, see <https://www.gnu.org/licenses/>.
#
############################################################################
#
#   * compile instructions: put this file and `utils.cs` in `steamapps`
#   * folder, open a terminal in the same folder, and execute:
#   *
#   * ```
#   *     chmod +x ${file}.cs
#   *     ./${file}.cs
#   * ```
#   *
#   * then the mod will be compiled automatically.
#   *
#   * Here we wrote a shebang like file, which is correct
#   * in my computer (Manjaro XFCE), if such script do not work
#   * in your computer, you could just try the instructions below :

export GAME_NAME="${0%\.cs}"                                # might modify if the name mismatch.
export GAME_DIR="$GAME_NAME"                                # might be modified, but "$GAME_NAME" cover most of the cases.

export FILE_NAME="$0"
export ASSEMBLY="Assembly-CSharp"                           # might be modified
export UTILS="utils.cs"                                     # might be modified if you do not put utils.cs in the current dir.
export PLUGIN_ID="Neutron3529.Cheat"                        # should be modified
export NAMESPACE_ID="Neutron3529.Cheat"                     # should be modified
export GAME_BASE_DIR="common/$GAME_DIR"                     # should modify GAME_DIR instead since GAME_DIR == GAME_NAME is almost always true.

export IFS=$'\n' # to disable the annoying space.
export DOTNET="dotnet" # the location of the DOTNET executable file.
[ -z "$DOTNET_CSC_DLL" ] && export DOTNET_CSC_DLL=`\ls /usr/share/dotnet/sdk/*/Roslyn/bincore/csc.dll` # In manjaro, the csc.dll is located in /usr/share/dotnet/sdk/*/Roslyn/bincore/csc.dll

__MODE_VERBOSE=99 # is the line number of "#define VERBOSE", may be modified
__MODE_DEBUG__=$((__MODE_VERBOSE+1))
__MODE_RELEASE=$((__MODE_DEBUG__+1))

case $1 in
    V)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    v)       _MODE__SELECT_=$__MODE_VERBOSE     ;;
    VERBOSE) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    verbose) _MODE__SELECT_=$__MODE_VERBOSE     ;;
    D)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    d)       _MODE__SELECT_=$__MODE_DEBUG__     ;;
    DEBUG)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    debug)   _MODE__SELECT_=$__MODE_DEBUG__     ;;
    *)       _MODE__SELECT_=$__MODE_RELEASE     ;;
esac

( yes "" | head -n $_MODE__SELECT_ | head -n-1  ; tail $FILE_NAME -n+$_MODE__SELECT_ ; cat $UTILS) | sed s/%%NAMESPACE_ID%%/${NAMESPACE_ID}/g | sed s/%%PLUGIN_ID%%/${PLUGIN_ID}/g | $DOTNET $DOTNET_CSC_DLL -nologo -t:library \
  -r:"${GAME_BASE_DIR}/BepInEx/core/BepInEx.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/core/0Harmony.dll" \
  -r:"${GAME_BASE_DIR}/BepInEx/core/BepInEx.Harmony.dll" \
  `[ -e "${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/netstandard.dll" ] && echo "-r:\"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/netstandard.dll\""` \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/System.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/System.Core.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.AIModule.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.CoreModule.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/UnityEngine.UI.dll" \
  -r:"${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/mscorlib.dll" \
  $(for i in "${GAME_BASE_DIR}/${GAME_NAME}_Data/Managed/$ASSEMBLY"*.dll ; do echo -e "-r:\"$i\"\n" ; done) \
  -out:"${GAME_BASE_DIR}/BepInEx/plugins/${FILE_NAME%.*}".dll \
  -optimize `[ "$_MODE__SELECT_" == "$__MODE_DEBUG__" ] && echo -debug` \
  - && rm -f "${GAME_BASE_DIR}/BepInEx/config/${PLUGIN_ID}.cfg";

if [ -n "$2" ]; then
    git add ${FILE_NAME}
    case $2 in
        R) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        r) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        RANDOM) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        random) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        U) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        u) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        UPLOAD) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        upload) git commit -am "`curl -s http://whatthecommit.com/index.txt`" ;;
        *) git commit -am "$2" ;;
    esac
    git push
fi
exit

#define VERBOSE // the line of __MODE_VERBOSE
#define DEBUG



using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Collections.Generic;

using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using UnityEngine;

namespace %%NAMESPACE_ID%%
{
    [BepInPlugin("%%PLUGIN_ID%%", "%%NAMESPACE_ID%%", "0.2.2")]
    public partial class Cheat : BaseUnityPlugin {
        void Start2() {
            // 主要逻辑放在`utils.cs`中，这里的start2只是为了以防万一
            // 目前来说，这个函数的唯一用途是用来“叮”……
            // 就像这样：
            logger("叮~修改器启动，请安心游戏");
            if(config.Bind("config", "dumpSomeData", true, "在log中输出全部丹方材料的五行，武器词条，技能效果，以及其他各种神奇数据").Value){
                foreach(PelletFormulaBook pb in AllDictionary.Dic_PelletFormulaBook.Values){
                    logger(pb.OutCome+":"+pb.Yuansus[0].ToString()+" "+pb.Yuansus[1].ToString()+" "+pb.Yuansus[2].ToString()+" "+pb.Yuansus[3].ToString()+" "+pb.Yuansus[4].ToString()+" ("+pb.ItemRequire+" - "+string.Join(" ",pb.materials)+")");
                }
                foreach(Materials m in AllDictionary.Dic_Material.Values){
                    logger(m.Name+":"+m.Jin+" "+m.Mu+" "+m.Shui+" "+m.Huo+" "+m.Tu);
                }
                foreach(string name in AllDictionary.Dic_BuffInfo.Keys){
                    BuffInfo b=AllDictionary.Dic_BuffInfo[name];
                    logger(name+" 名称 "+b.name+"  BUFF类型 "+b.buffType+"  影响属性 "+b.attriType+"  额外信息 "+b.extraInfo);
                }
                foreach(string name in AllDictionary.Dic_FabaoRandom_Entrys.Keys){
                    FbEntryInfo b=AllDictionary.Dic_FabaoRandom_Entrys[name];
                    logger(name+" 名称 "+b.name+"  BUFF类型 "+b.buff+"  描述 "+b.descrption);
                }
                foreach(string name in AllDictionary.Dic_SkillInfo.Keys){
                    TbsFramework.Skill.SkillInfo s=AllDictionary.Dic_SkillInfo[name];
                    logger(name+" 名称 "+s.skillName+"  2技能体系 "+s.skillSystem+"  子体系 "+s.childSystem+"  3攻击方式 "+s.attackType+"  4元素类型 "+s.MainYuansu+"  5选取范围 "+s.effectRange+"  6施法目标 "+s.releaseTarget+"  7施法范围 "+s.range+"  8消耗行动点数 "+s.cost+"  EffectOnHit \""+string.Join("\",\"",s.EffectOnHit)+"\"  1技能描述 "+s.Description);
                }
                foreach(string name in AllDictionary.Dic_EffectInfo.Keys){
                    EffectInfo s=AllDictionary.Dic_EffectInfo[name];
                    logger(name+" 效果名 "+s.Effectname+"  效果类型 "+s.Effectlist+"  影响属性 "+s.AttributeType+"  元素类型 "+s.YuanSu+"  伤害增幅类型 "+s.DamageType+"  持续时间 "+s.Duration+"  数值参数 "+s.Args+"  IsArgsFromHit0 "+s.IsArgsFromHit0+"  MaxStucks "+s.MaxStucks);
                }
                foreach(string name in AllDictionary.Dic_XinFa.Keys){
                    XinFa s=AllDictionary.Dic_XinFa[name];
                    logger(name+" 名称 "+s.Name+"  稀有度 "+s.rare+"  修炼类型 "+s.type+"  子体系 \""+string.Join("\",\"",s.childTypes)+"\"");
                }
                foreach(string name in AllDictionary.Dic_ShuFa.Keys){
                    ShuFa s=AllDictionary.Dic_ShuFa[name];
                    logger(name+" 名称 "+s.Name+"  稀有度 "+s.rare+"  等级 "+s.shufaRare+"  修炼体系 "+s.xiuliantype+"  子体系 \""+string.Join("\",\"",s.childXiuliantypes)+"\"");
                }
            }
        }
        [Desc("动画延迟乘数",0.2)]
        class Neutron3529Faster : Bfloat {
            public static float val;public void Init() {base.Init(ref val);}
            static IEnumerable<MethodBase> TargetMethods(){
                foreach(MethodInfo i in new MethodInfo[]{
                    typeof(SearchPanel).GetMethod("TextChange",(BindingFlags)(-1)),
//                     typeof(SayDialog).GetMethod("IconFlicker",(BindingFlags)(-1)),
                    typeof(CharaWalker).GetMethod("TypeString",(BindingFlags)(-1)),
                    typeof(DisplayPanel).GetMethod("DisplayOnPanel",(BindingFlags)(-1))
                }){
                    if(i==null){logger("FATAL:NULL i");}else{
                        logger("修改类别"+i.ToString()+"的MoveNext方法");
                        if(AccessTools.EnumeratorMoveNext(i)!=null){yield return AccessTools.EnumeratorMoveNext(i);}else{logger("error:i="+i.ToString()+", have no move next");}
                    }
                }
            }
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Newobj,typeof(UnityEngine.WaitForSeconds).GetConstructor(new Type[]{typeof(float)}))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Ldc_R4,val),
                            new CodeInstruction(OpCodes.Mul)
                        )
                        .Advance(1),logger
                    ).InstructionEnumeration();
                return instructions;
            }
        }
        [Desc("解除特性之间的相关性，并将特性最小得分设置为此数值",0)]
        [HarmonyPatch(typeof(EntryBuilder), "GetEntry")]
        class EntryBuilderGetEntry : Bint {
            public static int val;public void Init() {base.Init(ref val);}
            static void Prefix(int[] PoolRange, bool isPlayer){
                if (isPlayer){
                    PoolRange[0]=val;
                    PoolRange[1]=1000;
                }
            }
        }
        [Desc("roll人物时天赋点对属性的影响",0)]
        [HarmonyPatch(typeof(CreateChara_AttributesPart), "AddPoint",new Type[]{typeof(object),typeof(string)})]
        class CreateChara_AttributesPartAddPoint : Bint {
            public static int val;public void Init() {base.Init(ref val);}
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Dup),
                        new CodeMatch(OpCodes.Ldind_I4),
                        new CodeMatch(OpCodes.Ldc_I4_1),
                        new CodeMatch(OpCodes.Add)
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .Advance(2) // Move cursor to after ldfld
                        .SetAndAdvance(
                            OpCodes.Ldc_I4,val
                        )
                    ).InstructionEnumeration();
                return instructions;
            }
        }
        [Desc("炼丹产出乘数",0)]
        [HarmonyPatch(typeof(LianDan_LuziFunction), "currentOutPutNum",MethodType.Getter)]
        class LianDan_LuziFunctioncurrentOutPutNum : Bfloat {
            public static float val;public void Init() {base.Init(ref val);}
            static float Postfix(float result){
                return result*val;
            }
        }
        [Desc("初始人物词条点数（进入选择面板修改时生效）",45)]
        [HarmonyPatch(typeof(CreateChara_RandomEntryPanel), "init")]
        class CreateChara_RandomEntryPanelinit : Bint {
            public static int val;public void Init() {base.Init(ref val);}
            static void Postfix(ref int ___CurrentPoint,int ___MaxPoint){
                ___CurrentPoint+=val-___MaxPoint;
            }
        }
        [Desc("炼丹只出上品")]
        [HarmonyPatch(typeof(LianDan_LuziFunction), "GetAllOutpus")]
        class LianDan_LuziFunctionGetAllOutpus : Bbool {
            static List<PelletNameAndWeight> Postfix(List<PelletNameAndWeight> result){
                float counter=0f;
                foreach(PelletNameAndWeight x in result){
                    if(x.PelletName.Contains("·下品") || x.PelletName.Contains("·中品") ){
                        counter+=x.Weight;
                        x.Weight=0f;
                    } else if (x.PelletName.Contains("·上品")){
                        x.Weight+=counter;
                        counter=0f;
                    }
                }
                return result;
            }
        }
        [Desc("种植一回合完成")]
        [HarmonyPatch(typeof(PlantGrowFunction), "GetCurrentSpeed")]
        class PlantGrowFunctionGetCurrentSpeed : Bbool {
            static bool Prefix(ref float __result,float ___MaxProcess){
                __result=___MaxProcess;
                return false;
            }
        }
        [Desc("炼器一回合完成")]
        [HarmonyPatch(typeof(LianQiFunction), "currentLianQieRate",MethodType.Getter)]
        class LianQiFunctioncurrentLianQieRate : Bbool {
            static bool Prefix(ref float __result,float ___MaxProcess){
                __result=___MaxProcess;
                return false;
            }
        }
        [Desc("炼丹一回合完成")]
        [HarmonyPatch(typeof(LianDan_LuziFunction), "currentFireRate",MethodType.Getter)]
        class LianDan_LuziFunctioncurrentFireRate : Bbool {
            static bool Prefix(ref float __result,float ___MaxProcess){
                __result=___MaxProcess;
                return false;
            }
        }
        [Desc("额外词条，语法请参考mod源码，此处以0开头的词条会将词条效果设置为1，但不会显示数值","1&吸血&全属性效果&暴击率&命中率&人物好事件提升|3&大地图行动力提升&成丹值百分比提升&融合度百分比提升&火力值百分比提升|0&符箓距离增加&符箓不阻挡&丹药距离增加&丹药范围增加&稳固&免疫眩晕&免疫变形&免疫禁锢&免疫封禁|45&战斗移动距离提升&平时经验获取提升&战斗角色经验提升&心法经验提升&悟道进度百分比提升&术法精进提升&气运百分比提升&成丹值提升&融合度提升&火力值提升")]
        [HarmonyPatch(typeof(WholeObjects), "CreateAweaponFromFormula")]
        class WholeObjectsCreateAweaponFromFormula : Bstring {
            public static string val;
            public static bool equip_extra_citiao=true;
            public static Dictionary<float,string[]> extra_citiao=new Dictionary<float,string[]>();
            public static HashSet<string> all_extra_citiao=new HashSet<string>();
            public override bool Met(string confval)=>confval.Length>1 || equip_extra_citiao;
            public void Init() {
                equip_extra_citiao=config.Bind("config", "fabao_citiao_max", true, "法宝词条数量和效果变为最大").Value;
                base.Init(ref val);
                if(val.Length>0){
                    foreach(string s in val.Split('|')){
                        string[] ci=s.Split('&');
                        float f=float.Parse(ci[0]);
                        ci[0]="";
                        if(extra_citiao.ContainsKey(f)){
                            logger("额外词条出现了重复加成，这导致了语句 "+s+" 是无效的，你应当将加成相同的词条放在一起。");
                            continue;
                        }
                        for(int i=0;i<ci.Length;i++){
                            if(ci[i]=="")continue;
                            if(!all_extra_citiao.Add(ci[i])){
                                logger("在 "+s+" 中的词条 "+ci[i]+" 与前文重复，将其无效化");
                                ci[i]="";
                            }
                        }
                        extra_citiao.Add(f,ci);
                    }
                    logger("额外词条-patched");
                }
                if(equip_extra_citiao)logger("法宝词条数量和效果变为最大-patched");
            }
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldarg_1),
                        new CodeMatch(OpCodes.Ldfld,typeof(WeaponFormula).GetField("Outcome",(BindingFlags)(-1))),
                        new CodeMatch(i=>i.opcode==OpCodes.Callvirt && ((MethodInfo)i.operand).Name == "initialize")
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Dup)
                        )
                        .Advance(3)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Ldarg_2),
                            new CodeInstruction(OpCodes.Call,typeof(WholeObjectsCreateAweaponFromFormula).GetMethod("abconvert"))
                        )
                    ).InstructionEnumeration();
                return instructions;
            }
            public static void abconvert(AbstractWeapon abw,string s){
                if (s=="S_0" && abw.randomEntry.Count==0){
                    Weapon weapon = AllDictionary.Dic_Weapon[abw.Name];
                    if(equip_extra_citiao){
                        foreach(var entry in AllDictionary.Dic_FabaoRandom_Entrys.Keys) {
                            //if(all_extra_citiao.Contains(entry))continue;// 这个增加值与主动增加不同，故可以保留
                            // abstractWeapon.randomEntry.Add(EntryBuilder.GetRandomEntry(text2, weapon, null));
                            string text2="";
                            string text="+";
                            float num2;
                            FbEntryInfo fbEntryInfo = AllDictionary.Dic_FabaoRandom_Entrys[entry];
                            float computerValue2 = (float)(typeof(EntryBuilder).GetMethod("GetComputerValue",(BindingFlags)(-1)).Invoke(null,new object[]{fbEntryInfo.max, weapon.Level}));
                            if(computerValue2<=0)computerValue2=(float)(typeof(EntryBuilder).GetMethod("GetComputerValue",(BindingFlags)(-1)).Invoke(null,new object[]{fbEntryInfo.min, weapon.Level}));
                            if(fbEntryInfo.isInteger) {
                                int num=((int)computerValue2) * (1 + weapon.Level * (int)(1 + weapon.Rare) / 26);
                                num2=(float)num;
                                text2=num.ToString();
                            } else {
                                num2 = (float)Convert.ToInt32(computerValue2 * 100f)/100f;

                                if (fbEntryInfo.isPercentShow)
                                {
                                    text2 = num2.ToString("P0");
                                }
                                else
                                {
                                    text2 = num2.ToString("0.0");
                                }
                            }

                            if (num2 < 0f)
                            {
                                text = "";
                            }
                            text2 = fbEntryInfo.descrption + text + text2;
                            if(num2!=0f){
                                abw.randomEntry.Add(new RandomEntry{
                                    description = text2,
                                    name = fbEntryInfo.name,
                                    buffName = fbEntryInfo.buff,
                                    value = num2,
                                    id = Guid.NewGuid().ToString()
                                });
                            }
                        }
                    }
                    foreach(var kv in extra_citiao){
//                         logger("进入extra_citiao,k="+kv.Key+"v="+string.Join(" ",kv.Value));
                        foreach(var entry in kv.Value) {
                            if(AllDictionary.Dic_BuffInfo.ContainsKey(entry)){
                                BuffInfo buffInfo = AllDictionary.Dic_BuffInfo[entry];
                                var num2=kv.Key;
                                string text="";
                                string text2;
                                if (buffInfo.isPercentage || entry=="吸血" || entry=="全属性效果" || entry=="暴击率" || entry=="命中率") {
                                    text2 = num2.ToString("P0");
                                } else {
                                    text2 = num2.ToString("0.0");
                                }
                                if(num2<0f){
                                    text=text2;
                                }else if (num2>0f){
                                    text="+"+text2;
                                }else{
                                    num2=1f;
                                }
                                abw.randomEntry.Add(new RandomEntry{
                                    description = buffInfo.name + text,
                                    name = buffInfo.name,
                                    buffName = buffInfo.name,
                                    value = num2,
                                    id = Guid.NewGuid().ToString()
                                });
                            } else if (entry!=""){
                                logger("在Dic_FabaoRandom_Entrys信息中找不到"+entry);
                            }
                        }
                    }
                }
            }
        }

        [Desc("铁拳无敌（空拳可以殴打全体敌方单位，造成流血，眩晕等等异常状态）")]
        class IronFist : Bbool {
            public override void Init() {
                if(config.Bind("config", "iron_fist", true, "铁拳无敌（空拳可以殴打全体敌方单位，造成流血，眩晕）").Value){
                    // 这段程序在 WholeObjects.Awake 之后，因此可以直接修改数据。
                    if(AllDictionary.Dic_SkillInfo.ContainsKey("空拳")){
                        AllDictionary.Dic_SkillInfo["空拳"].effectRange="点";
                        AllDictionary.Dic_SkillInfo["空拳"].releaseTarget= TbsFramework.Skill.ReleaseTarget.所有敌方;
                        AllDictionary.Dic_SkillInfo["空拳"].range= 0f;
                        AllDictionary.Dic_SkillInfo["空拳"].cost= 1;
                        for(int i=0;i<1;i++){
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("伤口");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("剧毒");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("伤口不被抵抗");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("剧毒不被抵抗");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("金煞");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("寄生");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("剧毒");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("感电");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("燃烧");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("火蚀");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("溶蚀");
                            AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("虚空蚀");
                        }
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("驱散护盾");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("强制眩晕4s");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("脑溢血*");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("封禁5s");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("虚爆");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("风咒·倍");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("雨咒·极");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("强制致残14s");
    //                     AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("血蛊摄心·极*");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("血神诅咒");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("血流不止·极");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("极度恐惧");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("人运灭咒·伤");
                        AllDictionary.Dic_SkillInfo["空拳"].EffectOnHit.Add("人运灭咒·衰");
                        logger("铁拳无敌-patched");
                    }else{
                        logger("铁拳无敌：找不到“空拳”这个技能");
                    }
                }
            }
        }
        [Desc("将可堆叠物品掉落数量变为物品掉落数量最大值乘以此数值",1)]
        [HarmonyPatch(typeof(WholeObjects), "CreateDropItem")]
        class WholeObjectsCreateDropItem : Bsbyte {
            public static sbyte val;public void Init() {base.Init(ref val);}
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldfld,typeof(DropItem).GetField("minCount"))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .SetAndAdvance(
                            OpCodes.Ldfld,typeof(DropItem).GetField("maxCount")
                        )
                        .Advance(1)
                    ).InstructionEnumeration();
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldfld,typeof(DropItem).GetField("maxCount"))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .Advance(1)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Ldc_I4_S,(int)val),
                            new CodeInstruction(OpCodes.Mul)
                        )
                        .Advance(1)
                    ).InstructionEnumeration();
                return instructions;
            }
        }

        [Desc("将植物产量变为物品掉落数量最大值乘以此数值",10)]
        [HarmonyPatch(typeof(PlantGrowFunction), "GetOutPut")]
        class PlantGrowFunctionGetOutPut : Bsbyte {
            public static sbyte val;public void Init() {base.Init(ref val);}
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldfld,typeof(PlantClass).GetField("output_min"))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .SetAndAdvance(
                            OpCodes.Ldfld,typeof(PlantClass).GetField("output_max")
                        )
                        .Advance(1)
                    ).InstructionEnumeration();
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Ldfld,typeof(PlantClass).GetField("output_max"))
                    ).Repeat( matcher => // Do the following for each match
                        matcher
                        .Advance(1)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Ldc_I4_S,(int)val),
                            new CodeInstruction(OpCodes.Mul)
                        )
                        .Advance(1)
                    ).InstructionEnumeration();
                return instructions;
            }
        }
        [Desc("随机数设置为0(用于开启灭门/劫掠获取全部资源)")]
        class RandomEnhancement : Bbool {
            public static List<MethodInfo> randomEnhancement=new List<MethodInfo>();
            public override void Init() {
                if(config.Bind("config", "miemen_getall", true, "灭门获得全部资源").Value){
                    randomEnhancement.Add(typeof(Sect).GetMethod("BeDestroy",(BindingFlags)(-1)));
                    logger("随机数设置为0-灭门获得全部资源-added");
                }
                if(config.Bind("config", "robmen_getall", true, "劫掠门派获得全部资源").Value){
                    randomEnhancement.Add(typeof(Sect).GetMethod("BeRob",(BindingFlags)(-1)));
                    logger("随机数设置为0-劫掠门派获得全部资源-added");
                }
                if(config.Bind("config", "miecity_getall", true, "屠城获得全部资源").Value){
                    randomEnhancement.Add(typeof(City).GetMethod("Destroy",(BindingFlags)(-1)));
                    logger("随机数设置为0-屠城获得全部资源-added");
                }
                if(config.Bind("config", "robcity_getall", true, "劫掠城市获得全部资源").Value){
                    randomEnhancement.Add(typeof(City).GetMethod("BeRob",(BindingFlags)(-1)));
                    logger("随机数设置为0-劫掠城市获得全部资源-added");
                }
                base.Init(ref val);
            }
            static IEnumerable<MethodBase> TargetMethods(){
                foreach(MethodInfo m in randomEnhancement){
                    yield return m;
                }
            }
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Call,typeof(UnityEngine.Random).GetMethod("Range",new Type[]{typeof(int),typeof(int)}/*, and maybe some BindingFlags here*/))
                    ).Repeat( matcher =>
                        matcher
                        .Advance(1)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Pop),
                            new CodeInstruction(OpCodes.Ldc_I4_0)
                        )
                        .Advance(1),logger
                    ).InstructionEnumeration();
                return instructions;
            }
        }
        [Desc("灭门时 声望，门派善恶，玩家善恶 的改变量","1000,100,100")]
        [HarmonyPatch(typeof(BuildingManager), "AttackSect")]
        class BuildingManagerAttackSect : Bstring {
            public static string val;public void Init() {base.Init(ref val);}
            public static int a0=1000;
            public static int a1=100;
            public static int a2=100;
            public override void Patch(){
                var t=val.Split(',');
                a0=int.Parse(t[0]);
                a1=int.Parse(t[1]);
                a2=int.Parse(t[2]);
                base.Patch();
            }
            static void Postfix(){
                Sect sect = WholeObjects.Instance.Dic_Sect["S_0"];
                sect.shengWang += a0;
                sect.shanE += a1;
                WholeObjects.Instance.GetPlayer().shane += a2;
            }
        }
        [Desc("好事件的字面值概率")]
        [HarmonyPatch(typeof(ZhuangShiPanel), "GetBaseGoodEvent")]
        class ZhuangShiPanelGetBaseGoodEvent : Bbool {
            static bool Prefix(ref float __result){
                __result=10f;
                return false;
            }
        }
        [Desc("点击刷新弟子按钮时声望的增加值",200)]
        [HarmonyPatch(typeof(ZhuiSuiZhePanel), "ForceGetDizi")]
        class ZhuiSuiZhePanelForceGetDizi : Bint {
            public static int val;public void Init() {base.Init(ref val);}
            static void Prefix(){
                WholeObjects.Instance.GetPlayerSect().shengWang+=val;
            }
        }
        [Desc("追随者只刷新气运之子")]
        [HarmonyPatch(typeof(ZhuiSuiZhePanel), "ZhuiSuiZhe_Create")]
        class ZhuiSuiZhePanelZhuiSuiZhe_Create : Bbool {
            static IEnumerable<CodeInstruction> Transpiler(MethodBase __originalMethod, IEnumerable<CodeInstruction> instructions) {
                logger("%%PLUGIN_ID%%-正在注入类别"+__originalMethod.DeclaringType.Name+"的"+__originalMethod.Name+"方法");
                instructions = new CodeMatcher(instructions)
                    .MatchForward(false, // false = move at the start of the match, true = move at the end of the match
                        new CodeMatch(OpCodes.Call,typeof(GeneralUtils).GetMethod("RandomBornRare",new Type[]{typeof(int),typeof(int)}))
                    ).Repeat( matcher =>
                        matcher
                        .Advance(1)
                        .InsertAndAdvance(
                            new CodeInstruction(OpCodes.Pop),
                            new CodeInstruction(OpCodes.Ldc_I4_S,(int)Inborn.气运)
                        )
                        .Advance(1),logger
                    ).InstructionEnumeration();
                return instructions;
            }
        }

        [Desc("初始物品增加,1 全心法 2 全术法 4 全法宝配方 8 全丹药配方 16 全阵图配方 32 全植物999",63)]
        [HarmonyPatch(typeof(WholeObjects), "GetDropTermItems")]
        class WholeObjectsGetDropTermItems : Bsbyte {
            public static sbyte val;public void Init() {base.Init(ref val);}
            static List<ItemStored> Postfix(List<ItemStored> list, WholeObjects __instance, string dropTermID){
                if(dropTermID!="玩家门派初始物品"){return list;}
                if((val&1)==1){
                    list=list.Where(x=>x.type!=ItemType.心法书).ToList();
                    foreach(var shu in AllDictionary.Dic_XinFa.Values){
                        list.Add(__instance.CreateAXinfaBook(shu.Name, "", -1, false));
                    }
                }
                if((val&2)==2){
                    list=list.Where(x=>x.type!=ItemType.术法书).ToList();
                    foreach(var shu in AllDictionary.Dic_ShuFa.Values){
                        list.Add(__instance.CreateAShuFaBooK(shu.Name, "", false));
                    }
                }
                if((val&4)==4){
                    list=list.Where(x=>x.type!=ItemType.法宝配方).ToList();
                    foreach(var shu in AllDictionary.Dic_WeaponFormula.Values){
                        list.Add((ItemStored)typeof(WholeObjects).GetMethod("CreateNormalItem",(BindingFlags)(-1)).Invoke(__instance,new object[]{shu.Name, "", 1, false}));
                    }
                }
                if((val&8)==8){
                    list=list.Where(x=>x.type!=ItemType.丹药配方).ToList();
                    foreach(var shu in AllDictionary.Dic_PelletFormulaBook.Values){
                        list.Add((ItemStored)typeof(WholeObjects).GetMethod("CreateNormalItem",(BindingFlags)(-1)).Invoke(__instance,new object[]{shu.Name, "", 1, false}));
                    }
                }
                if((val&32)==32){
                    list=list.Where(x=>!AllDictionary.Dic_Plant.ContainsKey(x.name)).ToList();
                    foreach(var shu in AllDictionary.Dic_Plant.Values){
                        if (AllDictionary.Dic_Item.ContainsKey(shu.PlantName)){
                            list.Add((ItemStored)typeof(WholeObjects).GetMethod("CreateNormalItem",(BindingFlags)(-1)).Invoke(__instance,new object[]{shu.PlantName, "", 999, false}));
                            if(AllDictionary.Dic_Material.ContainsKey(shu.PlantName)){
                                var m=AllDictionary.Dic_Material[shu.PlantName];
                                logger("植物"+m.Name+":"+m.Jin+" "+m.Mu+" "+m.Shui+" "+m.Huo+" "+m.Tu);
                            } else {
                                logger("植物"+shu.PlantName+"不存在对应材料？");
                            }
                        } else {
                            logger("植物名称："+shu.PlantName+" 不在AllDictionary.Dic_Plant中");
                        }
                    }
                }
                if((val&16)==16){
                    foreach(var shu in AllDictionary.Dic_StovePosBook.Values){
                        if((shu.Name[0]!="阴图"[0] || shu.Name[1]!="阴图"[1]) && (shu.Name[0]!="阳图"[0] || shu.Name[1]!="阳图"[1]) && (shu.Name[0]!="清图"[0] || shu.Name[1]!="清图"[1])){
                            list.Add((ItemStored)typeof(WholeObjects).GetMethod("CreateNormalItem",(BindingFlags)(-1)).Invoke(__instance,new object[]{shu.Name, "", 1, false}));
                        }
                    }
                }
                return list;
            }
        }
    }
}

